# -*- coding: utf-8 -*-
import pygame
import collidet
import math
import item,effect
import random

class bt_laser(pygame.sprite.Sprite):
    
    def __init__(self, belong_to, start_degree, end_degree):
        super(bt_laser, self).__init__(self.containers)
        self.belong_to = belong_to.belong_to
        self._belong_to = belong_to
        self.original_image = pygame.image.load("data/images/bt_laser.png")
        self.image = None
        self.rect = None
        self.start_degree = -start_degree
        self.end_degree = -end_degree
        self.current_degree = self.start_degree
        self.turn_intv = 10
        self.out_intv = 10
        self.out = False
        self.power = 5
        
        if end_degree <= start_degree :
            self.degree_step = 1
        else:
            self.degree_step = -1
        
        self.rotate()
        
    def update(self):
#        print "current_degree: ", self.current_degree
        if self.current_degree == self.end_degree:
            if self.out_intv == 0:
                self.light_out()
                return
            else:
#                print "light!"
                self.out_intv -= 1
        else:
            if self.turn_intv == 0 :
                self.current_degree += self.degree_step
            else:
                self.turn_intv -= 1
        self.rotate()

        length = math.sqrt((self.image.get_width() / 2.0) ** 2\
        + (self.image.get_height() / 2.0) ** 2)
        offx, offy = collidet.get_offsets(length, self.current_degree)
        self.rect.center = (self._belong_to.rect.centerx - offx, self._belong_to.rect.centery + offy)
        
    
    def rotate(self):
        self.image = pygame.transform.rotozoom(self.original_image, self.current_degree, 1.0)
        self.rect = self.image.get_rect()
        
    def draw(self, screen):
        screen.blit(self.image, self.rect)
 

    def light_out(self):
#        print "out!"
        self.out = True
        self.kill()

class bt_laser_enemy(pygame.sprite.Sprite):
    
    def __init__(self, belong_to, start_degree, end_degree):
        super(bt_laser_enemy, self).__init__(self.containers)
        self._belong_to = belong_to
        self.original_image = pygame.image.load("data/images/bt_laser_enemy.png")
        self.image = None
        self.rect = None
        self.start_degree = -start_degree
        self.end_degree = -end_degree
        self.current_degree = self.start_degree
        self.turn_intv = 10
        self.out_intv = 10
        self.out = False
        self.power = 2
        
        if end_degree <= start_degree :
            self.degree_step = 1
        else:
            self.degree_step = -1
        
        self.rotate()
        
    def update(self):
#        print "current_degree: ", self.current_degree
        if self.current_degree == self.end_degree:
            if self.out_intv == 0:
                self.light_out()
                return
            else:
#                print "light!"
                self.out_intv -= 1
        else:
            if self.turn_intv == 0 :
                self.current_degree += self.degree_step
            else:
                self.turn_intv -= 1
        self.rotate()

        length = math.sqrt((self.image.get_width() / 2.0) ** 2\
        + (self.image.get_height() / 2.0) ** 2)
        offx, offy = collidet.get_offsets(length, self.current_degree)
        self.rect.center = (self._belong_to.rect.centerx - offx, self._belong_to.rect.centery + offy)
        
    
    def rotate(self):
        self.image = pygame.transform.rotozoom(self.original_image, self.current_degree, 1.0)
        self.rect = self.image.get_rect()
        
    def draw(self, screen):
        screen.blit(self.image, self.rect)
 

    def light_out(self):
#        print "out!"
        self.out = True
        self.out = True
        self.kill()


class bt_laser_gun(pygame.sprite.Sprite):
    
    def __init__(self, belong_to, degree, speed):
        super(bt_laser_gun, self).__init__(self.containers)
        self.degree = degree
        self.original_image = pygame.image.load("data/images/bt_laser_gun.png")
        self.image = self.original_image
        self.forewoard_step = 5
        self.back_step = 5
        self.speed_x,self.speed_y = collidet.get_offsets(speed, degree)
        self.belong_to = belong_to
        self.laser1 = None
        self.laser2 = None
        self.rect = None
        self.not_fire = True
        self.off_set_x = 0
        self.off_set_y = 0
        self.on_fire = True
        
        self.rotate()
        
    def action(self):
        if self.on_fire:
            if self.forewoard_step :
                self.off_set_x += self.speed_x
                self.off_set_y += self.speed_y
                self.forewoard_step -= 1
            else:
                if self.not_fire:
                    self.laser1 = bt_laser(self, self.degree, self.degree + 120.0)
                    self.laser2 = bt_laser(self, self.degree, self.degree - 120.0)
                    self.not_fire = False
        else:
            if self.back_step :
                self.off_set_x -= self.speed_x
                self.off_set_y -= self.speed_y
                self.back_step -= 1
            else:
                self.kill()

        self.rect.center = (self.belong_to.rect.centerx + self.off_set_x,\
                            self.belong_to.rect.centery + self.off_set_y)
        
            
    def rotate(self):
        self.image = pygame.transform.rotozoom(self.original_image, -self.degree, 1.0)
        self.rect = self.image.get_rect()
        self.rect.center = (self.belong_to.rect.centerx, self.belong_to.rect.centery)
            
    def update(self):
#        print "in update"
        self.action()
        if not self.not_fire :
            if self.laser1 and self.laser1.out :
                self.laser1 = None
            if self.laser2 and self.laser2.out :
                self.laser2 = None
            
            if self.laser1 is None and self.laser2 is None:
#                print "Kill gun!"
#                self.kill()
                self.on_fire = False
        
    def draw(self, screen):
        screen.blit(self.image, self.rect)
        self.rotate()
        
    def action(self):
        if self.on_fire:
            if self.forewoard_step :
                self.off_set_x += self.speed_x
                self.off_set_y += self.speed_y
                self.forewoard_step -= 1
            else:
                if self.not_fire:
                    self.laser1 = bt_laser(self, self.degree, self.degree + 120.0)
                    self.laser2 = bt_laser(self, self.degree, self.degree - 120.0)
                    self.not_fire = False
        else:
            if self.back_step :
                self.off_set_x -= self.speed_x
                self.off_set_y -= self.speed_y
                self.back_step -= 1
            else:
                self.kill()

        self.rect.center = (self.belong_to.rect.centerx + self.off_set_x,\
                            self.belong_to.rect.centery + self.off_set_y)
        
            
    def rotate(self):
        self.image = pygame.transform.rotozoom(self.original_image, -self.degree, 1.0)
        self.rect = self.image.get_rect()
        self.rect.center = (self.belong_to.rect.centerx, self.belong_to.rect.centery)
            
    def update(self):
#        print "in update"
        self.action()
        if not self.not_fire :
            if self.laser1 and self.laser1.out :
                self.laser1 = None
            if self.laser2 and self.laser2.out :
                self.laser2 = None
            
            if self.laser1 is None and self.laser2 is None:
#                print "Kill gun!"
#                self.kill()
                self.on_fire = False
        
    def draw(self, screen):
        screen.blit(self.image, self.rect)


#-------------------魔导攻击
class helper(pygame.sprite.Sprite):

    def __init__( self, belong_to, pos ):
        
        super( helper, self ).__init__()
        self.image = belong_to.image
        self.image.set_colorkey( (255, 255, 255), pygame.RLEACCEL )

        self.rect = self.image.get_rect( center = pos )
        self.belong_to = belong_to
        self.attack_list = self.belong_to.attack_list
        self.score = 0
        self.exp = 0
        self.hp = 0
        self.mp_time_scale = 0
        self.mp = 0
        self.power = int(self.belong_to.power)
       
        self.screen_size = self.belong_to.screen_size

    def exp_update( self ):

        self.belong_to.score += self.score
        self.belong_to.hp += self.hp
        self.belong_to.exp += self.exp
        self.belong_to.exp_update() 
        
    def update( self ):
        self.belong_to.update()
        effect.flame_spot((self.rect.centerx , self.rect.centery + 20), 0, 2.5, 5, 50)

    def draw( self, screen ):
        screen.blit( self.image, self.rect )

    def test_move(self, pos_y):
        self.rect.centery = pos_y


class missile_magic_attack(pygame.sprite.Sprite):

    def __init__( self, belong_to ):

        super( missile_magic_attack, self ).__init__( self.containers )

        self.belong_to = belong_to
        self.image = self.belong_to.image
        self.rect = self.belong_to.rect
        self.power = self.belong_to.power
        self.origin_rect = self.rect
        
        self.helper_list = []
        self.initial_pos_list = []

        for i in xrange( 10 ):
            self.helper_list.append(helper( self.belong_to, (50*i + 30,640) ))
            self.initial_pos_list.append( random.randrange(600, 700, 30) )
 
        self.alpha = 255

        self.is_fire = True

    def update( self ):

        self.alpha -= 5
        if self.alpha <= 0:
            for h in self.helper_list:
                effect.spark_obj(h.rect.center, 'Line')
                h.kill()
            self.kill()

        if self.alpha > 150:
            index = 0
            for h in self.helper_list:
                h.test_move( self.initial_pos_list[index] - 255 + self.alpha  )
                index += 1
        else:
            if self.is_fire:
                for h in self.helper_list:
                    item.missile_luncher_obj( h, 2)
            self.is_fire = False

    def kill( self ):
        super( missile_magic_attack, self ).kill()

    def draw( self, screen ):
        for h in self.helper_list:
            h.draw( screen )
        pass

# steal hp
class enemy_hp_obj( pygame.sprite.Sprite ):

    def __init__( self, belong_to, target_obj, speed ):

        super( enemy_hp_obj, self ).__init__( self.containers )

        self.belong_to = belong_to
        self.target_obj = target_obj
        
        self.image = pygame.Surface( (10,10) )
        pygame.draw.ellipse( self.image,  random.choice( [ (255, 255, 255),
                              (255, 255, 0), (255, 200, 0) ] ), [0,0,10,10])
        self.image.set_colorkey((0,0,0), pygame.RLEACCEL)
        self.image.convert()
        self.rect = self.image.get_rect( center = self.belong_to.rect.center )

        self.speed = speed

    def get_shot_speed(self, speed = 7.5):
        #-------------------------------------------
        if self.target_obj is None or not self.target_obj.is_alived():
            return [0, speed]
        #--------------------------------------------
        dx = self.rect.centerx - self.target_obj.rect.centerx
        dy = self.rect.centery - self.target_obj.rect.centery
        if (dx != 0):
            l = float(dy) / dx
            speed_x = math.sqrt((float(speed ** 2) / float(1 + l ** 2)))
            speed_y = abs(l) * speed_x
            if (dx > 0):
                speed_x = -speed_x
            if (dy > 0):
                speed_y = -speed_y
        else:
            speed_x = 0
            if (dy > 0):
                speed_y = -speed
            else:
                speed_y = speed
        return [speed_x,speed_y]

    def update( self ):

        speed_x, speed_y = self.get_shot_speed(self.speed)
        self.rect = self.rect.move(speed_x, speed_y)
        effect.flame_spot((self.rect.centerx , self.rect.centery), -speed_x / 4.0, -speed_y / 4.0, 5, 20)
        
         
        if self.rect.colliderect( self.target_obj.rect ):
            if self.target_obj.hp < self.target_obj.max_hp:
                self.target_obj.hp += 5
            if self.target_obj.hp > self.target_obj.max_hp:
                self.target_obj.hp = self.target_obj.max_hp
            self.kill()
            

    def kill( self ):
        super( enemy_hp_obj, self ).kill()
    
    def draw( self, screen ):
        
        screen.blit( self.image, self.rect )
              


class steal_magic_attack( pygame.sprite.Sprite ):

    def __init__( self, belong_to ):

        super( steal_magic_attack, self ).__init__( self.containers )
        self.belong_to = belong_to
        self.attack_list = self.belong_to.attack_list

        self.steal_intv = 30
        self.stealing = 0
        
        self.image = pygame.Surface( (2,2) )
        pygame.draw.ellipse( self.image,  random.choice( [ (255, 255, 255),
                              (255, 255, 0), (255, 200, 0) ] ), [0,0,2,2])
        self.image.set_colorkey((0,0,0), pygame.RLEACCEL)
        self.image.convert()
        self.rect = self.image.get_rect()
        
        self.run_once = False
        
        self.enemy_hp = pygame.sprite.Group()
        enemy_hp_obj.containers = self.enemy_hp

        #--------------------------------------------
        self.speed = 10
        self.belong_to.is_be_shooted = False
        #--------------------------------------------



    def update( self ):
        
        if self.attack_list is None:
            return 
        if self.belong_to.is_be_shooted:
            self.kill()
            self.belong_to.is_be_shooted = False

        if self.stealing == 0 :
            
            self.stealing = self.steal_intv

            for attack_obj in self.attack_list:
                if attack_obj.is_alived() and not attack_obj.is_item:
                    enemy_hp_obj( attack_obj, self.belong_to, self.speed )
                    attack_obj.hp -= 5
                    if attack_obj.hp <= 0:
                        attack_obj.crashed()
                        self.belong_to.score += attack_obj.score
                        self.belong_to.exp += attack_obj.exp

        else:
            self.stealing -= 1
        
        for hp_obj in self.enemy_hp:
            hp_obj.update()
        
        self.belong_to.exp_update()
            

    def draw( self, screen ):

        for hp_obj in self.enemy_hp:
            hp_obj.draw( screen )
            
    def kill( self ):
        super( steal_magic_attack, self ).kill()

